package com.btcode.common;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import com.google.gson.Gson;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;

public class HttpConnUtil {
    // 数据解析
    private static final Gson GSON = new Gson();

    public HttpClient getHttpClient() throws NoSuchAlgorithmException, KeyManagementException {
       return null;
    }

    private static ThreadLocal<HttpClient> httpClientThreadLocal = new ThreadLocal<>();

    private static HttpClient getDefaultHttpClient(){
        HttpClient httpClient = httpClientThreadLocal.get();
        if(httpClient == null){
                httpClient = new HttpClient();
                httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
                httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);

                //HttpClient每主机并发连接数与最大连接数
                httpClient.getHttpConnectionManager().getParams().setDefaultMaxConnectionsPerHost(32);
                httpClient.getHttpConnectionManager().getParams().setMaxTotalConnections(128);
                httpClientThreadLocal.set(httpClient);
            }
        return httpClient;
    }

    /**
     * 根据给定的url地址返回相应的inputstream>>>
     */
    public static InputStream getConnInputStream(String urlStr) throws IOException {
        URL url = null;
        HttpURLConnection httpUrlCon = null;
        url = new URL(urlStr);
        httpUrlCon = (HttpURLConnection) url.openConnection();
        httpUrlCon.setDoInput(true);
        httpUrlCon.setDoOutput(true);
        httpUrlCon.setRequestMethod("GET");
        return httpUrlCon.getInputStream();
    }

    /**
     * 根据给定的url地址返回 该地�?��返回的文�?
     */
    public static String getConnInputStr(String urlStr) throws IOException {

        return getConnInputStr(urlStr, "utf-8");
    }

    /**
     * 根据给定的url地址返回 该地�?��返回的文�?
     */
    public static String getConnInputStr(String urlStr, String charEncoding) throws IOException {
        InputStream in = getConnInputStream(urlStr);
        InputStreamReader inputRead = new InputStreamReader(in, charEncoding);
        BufferedReader bufReader = new BufferedReader(inputRead);
        StringBuilder resultBuilder = new StringBuilder();
        for (String line = bufReader.readLine(); line != null; line = bufReader.readLine()) {
            resultBuilder.append("\n" + line);
        }
        bufReader.close();
        inputRead.close();
        in.close();
        return resultBuilder.toString();
    }

    /**
     * 根据给定的图片url地址，返回图片的byte[]
     */
    public static byte[] getWebImg(String urlStr) throws IOException {
        InputStream resultIn = getConnInputStream(
            "http://www.weather.gov.hk/images_s/tide/marine_map_gb.gif");
        ByteArrayOutputStream imageBytes = new ByteArrayOutputStream();
        for (int picByte = resultIn.read(); picByte != -1; picByte = resultIn.read()) {
            imageBytes.write(picByte);
        }
        byte[] bytes = imageBytes.toByteArray();
        return bytes;
    }

    /**
     * 向指定地�?ost数据
     */
    public static String postData(String url, NameValuePair[] pars, String chartSet)
        throws IOException {
        return postData(url, pars, chartSet, null);
    }

    /**
     * 向指定地�?ost数据
     */
    public static String postData(String url, NameValuePair[] pars, String chartSet,Header[] headers)
        throws IOException {
        HttpClient httpClient = getDefaultHttpClient();
        PostMethod postMethod = new PostMethod(url); //设置路径
        if (headers != null) {
            for (Header header : headers) {
                postMethod.setRequestHeader(header);
            }
        }
        try {
            postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, chartSet); //设置编码
            if(pars!=null){
                postMethod.setRequestBody(pars);   //设置传�?参数
            }
            HttpMethodParams params = new HttpMethodParams();
            params.setContentCharset(chartSet);
            postMethod.setParams(params);
            httpClient.executeMethod(postMethod);
            String result = postMethod.getResponseBodyAsString();
            return result;
        }
        catch (Exception e){
            throw e;
        }
        finally {
            postMethod.releaseConnection();
        }
    }

    /**
     * 向指定地�?ost数据
     */
    public static String getData(String url, NameValuePair[] pars, String chartSet,NameValuePair[] heardPars)
        throws IOException {

        HttpClient httpClient = getDefaultHttpClient();

        GetMethod getMethod = new GetMethod(url);

        getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, chartSet); //设置编码
        if(pars != null){
            getMethod.setQueryString(pars);
        }

        if(heardPars != null){
            for(NameValuePair nameValuePair:heardPars){
                getMethod.setRequestHeader(nameValuePair.getName() ,nameValuePair.getValue() );
            }
        }

        HttpMethodParams params = new HttpMethodParams();
        params.setContentCharset(chartSet);
        getMethod.setParams(params);

        if(heardPars != null){
            for(NameValuePair nameValuePair:heardPars){
                getMethod.setRequestHeader(nameValuePair.getName() ,nameValuePair.getValue() );
            }
        }

        httpClient.executeMethod(getMethod);
        String result = getMethod.getResponseBodyAsString();             //执行post…�?
        getMethod.releaseConnection();              //释放连接
        return result;
    }

    /**
     * 向指定地put数据
     */
    public static String putData(String url, NameValuePair[] pars, String chartSet)
        throws IOException {

        StringBuffer requestStrBuf = new StringBuffer();

        if(pars != null){
            for(int i=0;i<pars.length;i++){
                NameValuePair nameValuePair = pars[i];
                requestStrBuf.append("&"+nameValuePair.getName()+"=" + nameValuePair.getValue());
            }
        }

        String requestString = requestStrBuf.toString().replaceFirst("&", "");

        HttpClient httpClient = getDefaultHttpClient();

        PutMethod putMethod = new PutMethod(url); //设置路径
        putMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, chartSet); //设置编码

        putMethod.setRequestEntity(new StringRequestEntity(requestString,"application/x-www-form-urlencoded","utf-8"));
        httpClient.executeMethod(putMethod);
        String result = putMethod.getResponseBodyAsString();             //执行post…�?
        putMethod.releaseConnection();              //释放连接
        return result;
    }

    /**
     * post数据
     * @param url 请求地址
     * @param params 请求参数
     * @param type 返回结果类型，默认String.class，可以为空
     * @return 返回type类型的对象
     */
    public static <Result> Result postData(String url, Map<String, Object> params, Class<Result> type) throws IOException {
        HttpClient httpClient = getDefaultHttpClient();
        PostMethod postMethod = new PostMethod(url); //设置路径
        try {
            postMethod.getParams().setContentCharset("UTF-8"); //设置编码
            postMethod.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
            postMethod.setRequestBody(GSON.toJson(params));
            httpClient.executeMethod(postMethod);
            String result = postMethod.getResponseBodyAsString();
            if (type==null || type == String.class) {
                return (Result) result;
            }
            else {
                return new Gson().fromJson(result, type);
            }
        }
        finally {
            postMethod.releaseConnection();//释放连接
        }
    }

    /**
     * get数据
     * @param url 请求地址
     * @param type 返回结果类型，默认String.class，可以为空
     * @return 返回type类型的对象
     */
    public static <Result> Result getData(String url, Class<Result> type) throws IOException {
        HttpClient httpClient = getDefaultHttpClient();
        GetMethod method = new GetMethod(url);
        try{
            method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8"); //设置编码
            HttpMethodParams params = new HttpMethodParams();
            params.setContentCharset("UTF-8");
            method.setParams(params);
            httpClient.executeMethod(method);
            String result = method.getResponseBodyAsString();
            if (type==null || type == String.class) {
                return (Result) result;
            }
            return new Gson().fromJson(result, type);
        }finally {
            method.releaseConnection();//释放连接
        }
    }

    /**
     * get数据
     * @param url 请求地址
     * @return 返回type类型的对象
     */
    public static String getData(String url) throws IOException {
        return getData(url, String.class);
    }

    /**
     * post数据
     * @param url 请求地址
     * @param params 请求参数
     * @return 返回type类型的对象
     */
    public static String postData(String url, Map<String, Object> params) throws IOException {
        return postData(url, params, String.class);
    }
}
